Java Image Tool class instance based on Decorator Pattern [With demo source code download]
- 2020-10-23 20:58:29
- OfStack
This article gives an example of Java's image utility class based on decorator pattern. To share for your reference, the details are as follows:
ImgUtil. java:
/*
* Decorator pattern implements the image processing tool class
* similar java the io flow -
* Img Similar low-level streams can be used independently
* Press and Resize Similar high level flow
* Need to depend on the lower stream
*/
package util;
import java.io.File;
import java.util.List;
/**
* Picture tool class ( decorator ) And pictures ( Be decorator ) Public interface
* @author xlk
*/
public interface ImgUtil {
/** Adornment method - Processing images */
List<File> dispose();
}
AbstractImgUtil. java:
package util;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
/**
* Abstract image tool class - Abstract decorator
* @author xlk
*/
public abstract class AbstractImgUtil implements ImgUtil {
private ImgUtil imgUtil;
@Override
public List<File> dispose() {
return imgUtil.dispose();
}
public AbstractImgUtil(){}
public AbstractImgUtil(ImgUtil imgUtil) {
this.imgUtil = imgUtil;
}
/**
* Determine if the file is an image
* @param file The judged document
* @return Photos back true Non-image return false
* @throws IOException
*/
public static boolean isImg(File file) {
if (file.isDirectory()) {
return false;
}
try {
ImageInputStream iis = ImageIO.createImageInputStream(file);
Iterator<ImageReader> iter = ImageIO.getImageReaders(iis);
if (!iter.hasNext()) {// A file is not a picture
return false;
}
return true;
} catch (IOException e) {
return false;
}
}
}
Press. java:
package util;
import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
/**
* watermarking - decorator
* @author xlk
*/
public class Press extends AbstractImgUtil {
private List<File> src; // Picture path set
private String waterImg;// Watermark image path
private Integer x; // The offset to the left of the watermark image from the target image , if x<0, It's right in the middle
private Integer y; // The offset of the watermark image from the top of the target image , if y<0, It's right in the middle
private float alpha; // Watermark transparency (0.0 -- 1.0, 0.0 To be completely transparent, 1.0 Is completely opaque )
@Override
public List<File> dispose() {
src = super.dispose();
return press();
}
/** watermarking - Specific decoration method */
private List<File> press() {
if (waterImg==null || "".equals(waterImg)) {
throw new RuntimeException(" The watermark path cannot be empty ");
}
if (!isImg(new File(waterImg))) {
throw new RuntimeException(" The watermark path points to a file that is not an image ");
}
if (src.size()<=0) {
return src;
}
if (x!=null && y!=null) {
for (File f: src) {
press(f.getPath(), waterImg, f.getParent(), x, y, alpha);
}
} else {
for (File f: src) {
press(f.getPath(), waterImg, f.getParent(), alpha);
}
}
return src;
}
public Press() {}
public Press(ImgUtil imgUtil, String waterImg, float alpha) {
super(imgUtil);
this.waterImg = waterImg;
this.alpha = alpha;
}
public Press(ImgUtil imgUtil, String waterImg, Integer x, Integer y, float alpha) {
super(imgUtil);
this.waterImg = waterImg;
this.x = x;
this.y = y;
this.alpha = alpha;
}
public String getWaterImg() {
return waterImg;
}
public void setWaterImg(String waterImg) {
this.waterImg = waterImg;
}
public Integer getX() {
return x;
}
public void setX(Integer x) {
this.x = x;
}
public Integer getY() {
return y;
}
public void setY(Integer y) {
this.y = y;
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
}
/** Add image watermark */
private static void press(String src, String waterImg, String target, int x, int y, float alpha) {
File newFile = null;
try {
File file = new File(src);
Image image = ImageIO.read(file);
int width = image.getWidth(null);
int height = image.getHeight(null);
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bufferedImage.createGraphics();
g.drawImage(image, 0, 0, width, height, null);
Image waterImage = ImageIO.read(new File(waterImg)); // Watermark file
int width_1 = waterImage.getWidth(null);
int height_1 = waterImage.getHeight(null);
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
int widthDiff = width - width_1;
int heightDiff = height - height_1;
if (x < 0) {
x = widthDiff / 2;
} else if (x > widthDiff) {
x = widthDiff;
}
if (y < 0) {
y = heightDiff / 2;
} else if (y > heightDiff) {
y = heightDiff;
}
g.drawImage(waterImage, x, y, width_1, height_1, null); // End of watermark file
g.dispose();
File dir = new File(target);
if (!dir.exists()) {
dir.mkdirs();
}
newFile = new File(target + File.separator + file.getName());
ImageIO.write(bufferedImage, "jpg", newFile);
} catch (IOException e) {
e.printStackTrace();
}
}
/** Tile to add image watermark */
private static void press(String src, String waterImg, String target, float alpha) {
File newFile = null;
try {
File file = new File(src);
Image image = ImageIO.read(file);
int width = image.getWidth(null);
int height = image.getHeight(null);
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bufferedImage.createGraphics();
g.drawImage(image, 0, 0, width, height, null);
Image waterImage = ImageIO.read(new File(waterImg)); // Watermark file
int width_1 = waterImage.getWidth(null);
int height_1 = waterImage.getHeight(null);
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
int rpt_x = width>width_1?(int)Math.ceil(Double.valueOf(width)/width_1):1;//x Number of directional repeats
int rpt_y = height>height_1?(int)Math.ceil(Double.valueOf(height)/height_1):1;//y Number of directional repeats
for (int i=0; i<rpt_x; i++) {
for (int j=0; j<rpt_y; j++) {
g.drawImage(waterImage, i*width_1, j*height_1, width_1, height_1, null);
}
}// End of watermark file
g.dispose();
File dir = new File(target);
if (!dir.exists()) {
dir.mkdirs();
}
newFile = new File(target + File.separator + file.getName());
ImageIO.write(bufferedImage, "jpg", newFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Resize. java:
package util;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
/**
* The zoom - decorator
* @author xlk
*/
public class Resize extends AbstractImgUtil {
/** Scale different boundary colors */
private static final Color color = new Color(230,230,230);
private List<File> src; // Picture path set
private int height; // Post-treatment height
private int width; // Processed width
private double ratio; // After treatment, aspect ratio
private boolean bb; // Whether to fill when the proportion is wrong
@Override
public List<File> dispose() {
src = super.dispose();
return resize();
}
/** The zoom - Specific decoration method */
private List<File> resize() {
if (src.size()<=0) {
return src;
}
if (ratio>0) {
for (File f: src) {
resize(f.getPath(), f.getParent(), ratio, bb);
}
} else if (height>0 && width>0) {
for (File f: src) {
resize(f.getPath(), f.getParent(), height, width, bb);
}
}
return src;
}
public Resize() {}
public Resize(ImgUtil imgUtil, int height, int width, boolean bb) {
super(imgUtil);
this.height = height;
this.width = width;
this.bb = bb;
}
public Resize(ImgUtil imgUtil, double ratio, boolean bb) {
super(imgUtil);
this.ratio = ratio;
this.bb = bb;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public double getRatio() {
return ratio;
}
public void setRatio(double ratio) {
this.ratio = ratio;
}
public boolean isBb() {
return bb;
}
public void setBb(boolean bb) {
this.bb = bb;
}
/** zooming - According to the size */
private static void resize(String src, String target, int height, int width, boolean bb) {
File newFile = null;
try {
double ratio = 0; // scaling
File f = new File(src);
BufferedImage bi = ImageIO.read(f);
Image itemp = bi.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH);
// Calculate percentage
if (Double.valueOf(bi.getHeight())/bi.getWidth() > Double.valueOf(height)/width) {
ratio = Double.valueOf(height) / bi.getHeight();
} else {
ratio = Double.valueOf(width) / bi.getWidth();
}
AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);
itemp = op.filter(bi, null);
if (bb) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.setColor(color);
g.fillRect(0, 0, width, height);
if (width == itemp.getWidth(null))
g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null), itemp.getHeight(null), color, null);
else
g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null), itemp.getHeight(null), color, null);
g.dispose();
itemp = image;
}
File dir = new File(target);
if (!dir.exists()) {
dir.mkdirs();
}
newFile = new File(target + File.separator + f.getName());
ImageIO.write((BufferedImage) itemp, "jpg", newFile);
} catch (IOException e) {
e.printStackTrace();
}
}
/** zooming - By aspect ratio */
private static void resize(String src, String target, double ratio, boolean bb) {
File newFile = null;
try {
File f = new File(src);
BufferedImage bi = ImageIO.read(f);
// Computing size
int width = bi.getWidth();
int height = bi.getHeight();
if (Double.valueOf(height)/width<ratio) {
height = (int)(width*ratio);
} else {
width = (int)(Double.valueOf(height)/ratio);
}
Image itemp = bi.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH);
AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(1, 1), null);
itemp = op.filter(bi, null);
if (bb) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.setColor(color);
g.fillRect(0, 0, width, height);
if (width == itemp.getWidth(null))
g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null), itemp.getHeight(null), color, null);
else
g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null), itemp.getHeight(null), color, null);
g.dispose();
itemp = image;
}
File dir = new File(target);
if (!dir.exists()) {
dir.mkdirs();
}
newFile = new File(target + File.separator + f.getName());
ImageIO.write((BufferedImage) itemp, "jpg", newFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Img. java:
package util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* The picture - The original component
* @author xlk
*/
public class Img implements ImgUtil {
private String src; // Source image or image folder path
private String target; // Destination folder path
private boolean inner; //true- Include subfolders , false- Current folder only
@Override
public List<File> dispose() {
return copy();
}
/** copy - The initial state of the decorator */
private List<File> copy() {
if (src==null || "".equals(src) || target==null || "".equals(target)) {
throw new RuntimeException(" The source path or target path cannot be empty ");
}
File srcFile = new File(src);
List<File> list = new ArrayList<File>();
File targetDir = new File(target);
if (!targetDir.exists()) {
targetDir.mkdirs();
}
a:
if (srcFile.isDirectory()) {// The source path is the folder
File[] subs = srcFile.listFiles();
if (subs.length<=0) {
break a;
}
for (File sub: subs) {
if (sub.isDirectory() && inner) {
list.addAll(new Img(sub.getPath(), target+File.separator+sub.getName(), true).copy());
} else if (AbstractImgUtil.isImg(sub)) {
list.add(copy(sub, target));
}
}
} else if (AbstractImgUtil.isImg(srcFile)) {// The source path is the image
list.add(copy(srcFile, target));
}
return list;
}
private File copy(File file, String target) {
FileInputStream fis = null;
FileOutputStream fos = null;
File newFile = null;
try {
fis = new FileInputStream(file);
newFile = new File(target + File.separator + file.getName());
fos = new FileOutputStream(newFile);
byte[] bs = new byte[1024*10];
int len = -1;
while ((len=fis.read(bs))!=-1) {
fos.write(bs, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fis!=null) {
fis.close();
}
if (fos!=null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return newFile;
}
public Img() {}
public Img(String src, String target) {
this.src = src;
this.target = target;
}
public Img(String src, String target, boolean inner) {
this.src = src;
this.target = target;
this.inner = inner;
}
public String getSrc() {
return src;
}
public void setSrc(String src) {
this.src = src;
}
public String getTarget() {
return target;
}
public void setTarget(String target) {
this.target = target;
}
public boolean isInner() {
return inner;
}
public void setInner(boolean inner) {
this.inner = inner;
}
}
Click here to download the complete example code.
For more java related content, please refer to the following topics: Java Object-oriented Programming Introduction and Advanced Tutorial, Java Data Structure and Algorithm Tutorial, Java DOM Node Operation Skills Summary, Java File and Directory Operation Skills Summary and Java Cache operation Skills Summary.
I hope this article has been helpful in java programming.